home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
batchut
/
rbsetnv1.zip
/
WILDARGV.C
< prev
Wrap
Text File
|
1991-01-03
|
6KB
|
359 lines
/*
* setargv.c -> parse arguments
*
* This code evolved out of a requirement for expansion of wild-card
* arguments given on the command line. Turbo C's wildarg.obj
* actually produces a reference to __wildargv, which still doesn't
* do the job I needed (for example, directory names are not
* expanded).
*
* This version both expands wild-card arguments and converts them
* to lower case (a cosmetic thing for me). Arguments that are
* quoted (with either " or ') are left alone, but the quote
* characters are stripped. A leading quote may be escaped with
* a backslash (\" or \'). Quotes within arguments (ARG="a b c")
* are not handled in the Un*x fashion. If no matching filename
* is found, the argument is passed unchanged.
*
* Two conditional-compilation flags are provided:
* FIXARG0: convert argv[0] to lower case and switch
* all backslashes to slashes (cosmetic)
* SORTARGS: use qsort() to sort the expansions of
* each argument
*
* Further enhancements greatly appreciated.
*
* This code placed in the public domain on October 25, 1989 by
* its original author, Frank Whaley.
*
* Added check for '[' and ']' R. Brittain 4/21/90
* for use with wildunix TSR
*/
#define MAXARG 1024 /* max arguments */
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <mem.h>
#include <string.h>
#include <alloc.h>
/* let's do some things with macros... */
#define ISQUOTE(c) (((c)=='"')||((c)=='\''))
#define ISBLANK(c) (((c)==' ')||((c)=='\t'))
static char *cl; /* -> local copy of command line */
/* the following are used by run-time startup (c0?.obj) */
extern int _argc; /* number of args */
extern char **_argv; /* arg ptrs */
/* forward declarations */
static void *allocopy(void *src, int len);
static void getreg(char *av[]);
static void getwild(char *av[]);
/*
* _setargv() -> set argument vector
*/
void
_setargv()
{
char buf[128]; /* working buffer */
char far *cline; /* generic far ptr */
char *av[MAXARG]; /* working vector */
int len; /* command line length */
/* copy program name from environment */
cl = buf;
cline = MK_FP(*(int far *)MK_FP(_psp, 0x2c), 0);
while ( *cline )
{
if ( !*++cline )
{
cline++;
}
}
cline += 3;
while ( *cline )
{
#ifdef FIXARG0
*cl = tolower(*cline++);
if ( *cl == '\\' )
{
*cl = '/';
}
cl++;
#else
*cl++ = *cline++;
#endif
}
*cl = '\0';
av[0] = allocopy(buf, strlen(buf) + 1);
/* copy cmd line from PSP */
cl = buf;
cline = MK_FP(_psp, 0x80);
len = *cline++;
while ( len )
{
*cl++ = *cline++;
len--;
}
*cl = 0;
_argc = 1;
cl = buf;
while ( *cl )
{
/* deblank */
while ( ISBLANK(*cl) )
{
cl++;
}
/* pick next argument */
while ( *cl && (_argc < MAXARG) )
{
if ( iswild() )
{
getwild(av);
}
else
{
getreg(av);
}
/* deblank */
while ( ISBLANK(*cl) )
{
cl++;
}
}
}
/* copy argument vector */
_argv = allocopy(av, _argc * sizeof(char *));
}
/*
* does current argument contain a wildcard ??
*/
static int
iswild()
{
char *s = cl;
if ( ISQUOTE(*s) )
{
return ( 0 );
}
while ( *s && !ISBLANK(*s) )
{
if ( (*s == '\\') && ISQUOTE(*(s + 1)) )
{
s += 2;
}
else if ( (*s == '?') || (*s == '*') || (*s == '[') || (*s == ']'))
{
return ( 1 );
}
s++;
}
return ( 0 );
}
/*
* allocopy() -> allocate space for a copy of something
*/
static void *
allocopy(void *src, int len)
{
void *copy;
copy = sbrk(len);
if ( copy == (void *)(-1) )
{
write(2, "\nMemory shortage\n", 17);
exit(1);
}
return ( memcpy(copy, src, len) );
}
/*
* getreg() -> pick a regular argument from command line
*/
static void
getreg(char *av[])
{
char buf[128];
char *bp = buf;
char quote;
/* copy argument (minus quotes) into local buffer */
if ( ISQUOTE(*cl) ) {
quote = *cl++;
while ( *cl&& (*cl != quote) )
{
*bp++ = *cl++;
}
} else {
while ( *cl && !ISBLANK(*cl) ) {
if ( (*cl == '\\') && ISQUOTE(*(cl + 1)) )
{
cl++;
}
*bp++ = *cl++;
}
}
*bp = '\0';
/* skip over terminator char */
if ( *cl )
{
cl++;
}
/* store ptr to copy of string */
av[_argc++] = allocopy(buf, strlen(buf) + 1);
}
/*
* lwrcat() -> concatenate strings, conver to lower case
*/
static char *
lwrcat(char *s, char *t)
{
char *cp = s;
while ( *cp )
{
cp++;
}
/* avoid a warning */
while ( *t )
{
*cp++ = tolower(*t++);
}
*cp = '\0';
return ( s );
}
/*
* pickpath() -> pick pathname from argument
*/
static void
pickpath(char *arg, char *path)
{
char *t;
int n;
/* find beginning of basename */
for ( t = arg + strlen(arg) - 1; t >= arg; t-- )
{
if ( (*t == '\\') || (*t == '/') || (*t == ':') )
{
break;
}
}
/* pick off path */
for ( n = (t - arg) + 1, t = arg; n--; )
{
*path = tolower(*t);
path++;
t++;
}
*path = '\0';
}
#ifdef SORTARGS
/*
* mycmp() -> comparison routine for qsort()
*/
static int
mycmp(char **s, char **t)
{
return ( strcmp(*s, *t) );
}
#endif
/*
* getwild() -> get wildcard argument from command line
*/
static void
getwild(char *av[])
{
char path[128];
char srch[128];
char *s = srch;
struct ffblk f;
#ifdef SORTARGS
char **firstv = &av[_argc];
int nmatched = 0;
#endif
/* pick search string */
while ( *cl && !ISBLANK(*cl) )
{
*s++ = *cl++;
}
*s = '\0';
pickpath(srch, path);
if ( findfirst(srch, &f, 0x17) )
{
/* no match, just copy argument */
av[_argc++] = allocopy(srch, strlen(srch) + 1);
return;
}
/* add name if not "." or ".." */
if ( f.ff_name[0] != '.' )
{
strcpy(srch, path);
lwrcat(srch, f.ff_name);
av[_argc++] = allocopy(srch, strlen(srch) + 1);
#ifdef SORTARGS
nmatched++;
#endif
}
/* find the rest */
while ( !findnext(&f) && (_argc < MAXARG) )
{
if ( f.ff_name[0] != '.' )
{
strcpy(srch, path);
lwrcat(srch, f.ff_name);
av[_argc++] = allocopy(srch, strlen(srch) + 1);
#ifdef SORTARGS
nmatched++;
#endif
}
}
#ifdef SORTARGS
/* sort these entries */
qsort(firstv, nmatched, sizeof(char *), mycmp);
#endif
}
/*
* END of setargv.c
*/